import { ElMessage } from 'element-plus'
import { removeToken } from '@/utils/auth'
import store from '@/store'
var wsurl = ''
let ws: WebSocket | null = null
let weboscket_callback: any
let timeoutObj: any = null
let serverTimeoutObj: any = null
let lockReconnect = false // 避免ws重复连接
let connectNum = 0
// 获取 websocket 推送的数据
const websocketonmessage = (e: any) => {
  heartCheck.reset()
  heartCheck.start()
  connectNum = 0
  if (e.data === 'pong') {
    // console.log(e)
  } else if (e.data === 'logOut') {
    ElMessage({
      type: 'error',
      message: '该账号已在其它设备登录'
    })
    setTimeout(() => {
      store.dispatch('user/logout').then(() => {})
    }, 2000)
  } else {
    console.log(e.data, 'websocketonmessage====')
    return weboscket_callback(e)
  }
}

// 连接成功
const websocketonopen = () => {
  heartCheck.reset()
  heartCheck.start()
  connectNum = 0
  console.log('连接 websocket 成功')
}

// 连接失败时重新连接
const websocketonerror = () => {
  reconnect(wsurl)
}

// 断开链接后报错
const websocketclose = (e: any) => {
  console.log('断开连接', e)
  reconnect(wsurl)
}

// 手动关闭 websocket
const closewebsocket = () => {
  ws.close()
}

const initWebSocket = (url: string) => {
  wsurl = url
  // 初始化 websocket
  ws = new WebSocket(wsurl)
  ws.onmessage = websocketonmessage
  ws.onopen = websocketonopen
  ws.onerror = websocketonerror
  ws.onclose = websocketclose
}

// 发送数据
const sendData = (info: any) => {
  //  判断 data 数据类型
  let data = ''
  if (typeof info === 'string') {
    data = info
  } else {
    data = JSON.stringify(info)
  }

  //  判断 websocket 的状态
  if (ws.readyState === ws.OPEN) {
    // 已经打开,可以直接发送
    ws.send(data)
  } else if (ws.readyState === ws.CONNECTING) {
    // 正在开启状态中,则 1 秒后重新发送
    setTimeout(() => {
      ws.send(data)
    }, 1000)
  } else {
    // 未打开，则开启后重新调用
    reconnect(wsurl)
    sendData(data)
  }
}
// 接受数据
const acceptData = (callback: any) => {
  weboscket_callback = callback
}

// 重连机制
function reconnect(url: string) {
  if (lockReconnect || connectNum > 60) return
  lockReconnect = true
  setTimeout(function () {
    // 没连接上会一直重连，设置延迟避免请求过多
    initWebSocket(url)
    lockReconnect = false
    connectNum++
  }, 5000)
}

// 心跳检测
const heartCheck = {
  reset: function () {
    clearTimeout(timeoutObj)
    clearTimeout(serverTimeoutObj)
  },
  start: function () {
    timeoutObj = setTimeout(function () {
      // 这里发送一个心跳，后端收到后，返回一个心跳消息，
      // onmessage拿到返回的心跳就说明连接正常
      ws.send('ping')
      // console.log('ping!')
      serverTimeoutObj = setTimeout(function () {
        console.log('超时关闭')
        // 如果超过1分钟还没重置，说明后端主动断开了
        ws.close() // 如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
      }, 600000)
    }, 30000)
  }
}

// 返回data枚举,
// const data = {
//   'logOut': '退出直播中控',
//   'pong': 'socket通讯正常'
// }

// 返回data.type枚举,
// const data = {
//   type: {
//     'publish': '直播推流',
//     'publish_done': '直播断流',
//     'live_publish': '直播开始',
//     'live_stop': '直播结束',
//     'live_audit': '直播审核',
//     'message_audit': '互动消息审核',
//     'enter_roon': '进入房间',
//     'leave_roon': '离开房间',
//     'draw_prize_notice': '福袋开奖通知'
//   }
// }

// 导出
export { initWebSocket, sendData, acceptData, closewebsocket }
